home *** CD-ROM | disk | FTP | other *** search
Wrap
/* * Main module * * Copyright (c) Clever Bits and Bitgate Software 1993 * All Rights Reserved. * * The main module * * Update log: * * [20.12.92 - 12.9.93] Karl A. 0ygard * not documented * [24.9.93 - 8.10.93] Ken Hollis * WMsgWindow * WM_REDRAW - put in window text stuff * [31.10.93 - 26.3.94] Ken Hollis and Karl 0ygard * WDoDial - fixed and optimized cursor controls * - removed 'handled' variable * - removed just_created and WM_INIT stuff * - optimised dragging of windows and stuff * - removed call to WKillAllWindows at end * - fixed bug in WM_TOPPED * - changed code in WM_TOPPED; when background window * is just _clicked_ it is topped - if mouse button * is _pressed_ in window, objects in window are * selected * - removed two useless (and failing) lines from * keyboard handler * - moved keyboard equivalents into here * - added help into the WDoDial feature * - fixed all cursor stuff so it works * - added form_alert for L_MOTIF look * - fixed W_BEVENT for TOUCHEXIT buttons * on background window events * - FLYING object is now background movable * - commented out global help for now * - keyboard scrollable text windows * - added double-click checking for desktop * - made it so objects may be clicked in a * topped window, but must be PRESSED in * an untopped window. Works better. * - added SELECTABLE bit to TOUCHEXIT * WInit - added setup for WAppl_Getinfo * - added standard look at bootup * - fixed EXTREMELY serious bug from nkcc * nkc_init placement. MUST BE AT THE * END OF ANY PROCEDURE! * - prgnameheader may be NULL. It is now allocated * WMsgWindow - added iconification of window support * - fixed WM_ARROWED stuff for text windows * - added the WScrollText routine * - finally fixed the amount_moved problems * - moved WM_NEWTOP and WM_ONTOP * - changed some code layout * - added WM_PAINT * WM_REDRAW - removed clipping * WM_CLOSED - removed turn off of cursor - not necessary * WM_CREATED - removed turn off of cursor - not necessary * WM_KILL - removed turn off of cursor - not necessary * - window is now relentlessly killed even if user * tries to stop it. * WTerm - fixed EXTREMELY serious bug from nkcc * nkc_term placement. MUST BE AT THE * END OF ANY PROCEDURE! * - made it nicer and more secure * WMenuBar - removed, placed in MENU.C * (global) - added new GEM 4.0+ messages * *prgnameheader - moved from windows.c and renamed prgnameheader * and added ": " for later use */ #include <stdlib.h> #include <stddef.h> #include <string.h> #include <vdi.h> #include <stdio.h> #include <time.h> #include "nkcc.h" #include "winlib.h" #ifndef __WINLIB__ #define __WINLIB__ #endif #ifdef __TURBOC__ #pragma warn -pia #endif GRECT desk; WINDOW *WindowChain; int Life, Return, VDIhandle, Ap_ID; char *desk_accessories[6]; OBJECT *wl_menubar = NULL; int gr_cw, gr_ch, gr_bw, gr_bh; int small_font, large_font, color_font; int num_colors, num_planes; int image_w, image_h, big_img; int hotkeylevel, buttonlevel, ColSupported; int WinLIBVersion, XVDIVersion, TextVersion, HotkeyVersion, HottextVersion; char *prgnameheader; BOOL DesktopInstalled, MenusShown; static char *___copyright = "*- WinLIB PRO Copyright © 1992-1994, Bitgate Software and Clever Bi" "ts. All Rights Reserved. This library is public domain, and may n" "ot be sold at any cost. It may be sold with a program only if that" " program contains the library. Programmed with Pure C 1.0 -*"; static char s1[] = " "; static char s2[] = " XXXXXXXXXXXXXXXXX "; static char s3[] = "--------------------"; static char s4[] = " Desk Accessory 1 "; static char s5[] = " Desk Accessory 2 "; static char s6[] = " Desk Accessory 3 "; static char s7[] = " Desk Accessory 4 "; static char s8[] = " Desk Accessory 5 "; static char s9[] = " Desk Accessory 6 "; OBJECT menu_object[] = { /* Tree #0*/ { -1, 1, 4,0x0019,0x0000,0x0000, (long)(0x00000000L), 0, 0, 80, 25}, { 4, 2, 2,0x0014,0x0000,0x0000, (long)(0x00001100L), 0, 0, 80, 513}, { 1, 3, 3,0x0019,0x0000,0x0000, (long)(0x00000000L), 2, 0, 6, 769}, { 2, -1, -1,0x0020,0x0000,0x0000, (long)(s1), 0, 0, 6, 769}, { 0, 5, 5,0x0019,0x0000,0x0000, (long)(0x00000000L), 0, 769, 80, 23}, { 4, 6, 13,0x0014,0x0000,0x0000, (long)(0x00ff1100L), 2, 0, 20, 8}, { 7, -1, -1,0x001c,0x0000,0x0000, (long)(s2), 0, 0, 20, 1}, { 8, -1, -1,0x001c,0x0000,0x0008, (long)(s3), 0, 1, 20, 1}, { 9, -1, -1,0x001c,0x0000,0x0000, (long)(s4), 0, 2, 20, 1}, { 10, -1, -1,0x001c,0x0000,0x0000, (long)(s5), 0, 3, 20, 1}, { 11, -1, -1,0x001c,0x0000,0x0000, (long)(s6), 0, 4, 20, 1}, { 12, -1, -1,0x001c,0x0000,0x0000, (long)(s7), 0, 5, 20, 1}, { 13, -1, -1,0x001c,0x0000,0x0000, (long)(s8), 0, 6, 20, 1}, { 5, -1, -1,0x001c,0x0020,0x0000, (long)(s9), 0, 7, 20, 1} }; OBJECT *MainMenu = menu_object; #define INTERNAL 0 /* Menu tree */ #define DESKA1 8 /* STRING in Tree INTERNAL */ #define DESKA2 9 /* STRING in Tree INTERNAL */ #define DESKA3 10 /* STRING in Tree INTERNAL */ #define DESKA4 11 /* STRING in Tree INTERNAL */ #define DESKA5 12 /* STRING in Tree INTERNAL */ #define DESKA6 13 /* STRING in Tree INTERNAL */ /* * Initialize everything * * ap_id = application id returned by appl_init * DeskWndDispatcher = window dispatcher for desktop * DestBtnDispatcher = mouse button dispatcher for desktop * MainDispatcher = dispatcher for all program-specific messages * KeyDispatcher = main key dispatcher * prgname = name of program (used in MTOS only, may be left NULL) * prgnameheader = name of program to use in window titlebars (may be left NULL) * * Returns TRUE on success */ GLOBAL int WInit(int ap_id, int *work_out, int DeskWndDispatcher(WINDOW *, int[]), int MainDispatcher(int[]), int KeyDispatcher(int), char *prgname, char *header, int dsk) { int extnd_out[57], attr[10]; /* WLINFO wlinf[] = {0x0059, 0x0012, 0x0020, 0x0010, 0x0010}; COOKIE *newcook; */ RFix_ObjectPos(MainMenu); if (AES_VERSION>0x0400) { menu_bar(MainMenu, 1); desk_accessories[1] = (char *) MainMenu[DESKA1].ob_spec.free_string; desk_accessories[2] = (char *) MainMenu[DESKA2].ob_spec.free_string; desk_accessories[3] = (char *) MainMenu[DESKA3].ob_spec.free_string; desk_accessories[4] = (char *) MainMenu[DESKA4].ob_spec.free_string; desk_accessories[5] = (char *) MainMenu[DESKA5].ob_spec.free_string; desk_accessories[6] = (char *) MainMenu[DESKA6].ob_spec.free_string; if (!strncmp((char *) desk_accessories[1], " Desk Accessory", 16)) desk_accessories[1] = NULL; if (!strncmp((char *) desk_accessories[2], " Desk Accessory", 16)) desk_accessories[2] = NULL; if (!strncmp((char *) desk_accessories[3], " Desk Accessory", 16)) desk_accessories[3] = NULL; if (!strncmp((char *) desk_accessories[4], " Desk Accessory", 16)) desk_accessories[4] = NULL; if (!strncmp((char *) desk_accessories[5], " Desk Accessory", 16)) desk_accessories[5] = NULL; if (!strncmp((char *) desk_accessories[6], " Desk Accessory", 16)) desk_accessories[6] = NULL; menu_bar(MainMenu, 0); } else { desk_accessories[1] = " Use accessories"; desk_accessories[2] = " Use accessories"; desk_accessories[3] = " Use accessories"; desk_accessories[4] = " Use accessories"; desk_accessories[5] = " Use accessories"; desk_accessories[6] = " Use accessories"; } if (!(WindowChain = malloc(sizeof(WINDOW)))) /* Allocate memory for WindowChain */ return FALSE; WindowChain->next = NULL; WindowChain->prev = NULL; wind_get(0, WF_WORKXYWH, &desk.g_x, &desk.g_y, &desk.g_w, &desk.g_h); wind_get(0, WF_CURRXYWH, &WindowChain->size.g_x, &WindowChain->size.g_y, &WindowChain->size.g_w, &WindowChain->size.g_h); WindowChain->WndDispatcher = malloc(sizeof(DeskWndDispatcher)); WindowChain->WndDispatcher = DeskWndDispatcher; WindowChain->handle = 0; WindowChain->state = W_OPEN | W_DESKTOP; WindowChain->kind = 0; WindowChain->menubar = 0; WindowChain->user = 0; WindowChain->timer.ev_mtcount = 0; WindowChain->timer.user = 0; VDIhandle = graf_handle(&gr_cw, &gr_ch, &gr_bw, &gr_bh); Ap_ID = ap_id; _MainDispatcher = malloc(sizeof(MainDispatcher)); _MainKeyDispatcher = malloc(sizeof(KeyDispatcher)); _MainDispatcher = MainDispatcher; _MainKeyDispatcher = KeyDispatcher; Life = TRUE; if (gr_cw < 7 || gr_ch < 7) { image_w = gr_cw << 1; image_h = gr_ch; big_img = FAIL; } else if (gr_ch > 14) { image_w = image_h = 16; big_img = TRUE; } else { image_w = 16; image_h = 8; big_img = FALSE; } init_images(); vq_extnd(VDIhandle, 1, extnd_out); init_mfdb(&screen, NULL, desk.g_w, desk.g_h, 0, work_out[4]); vqt_attributes(VDIhandle, attr); num_planes = extnd_out[4]; num_colors = work_out[13]; large_font = attr[7]; color_font = attr[1]; small_font = work_out[46]; ColSupported = work_out[13]; /* MultiTOS variable */ if (ColSupported < 0) ColSupported = 32767; /* True colour */ /* create_cookie(&newcook, 'WLIB', (long) wlinf); new_cookie(newcook); */ if (header) { prgnameheader = malloc(strlen(header) + 2); strcpy(prgnameheader, header); strcat(prgnameheader, ": "); } else prgnameheader = strdup(""); hotkeylevel = HOTKEY_UNDERLINE; buttonlevel = WS_XED; if (AES_VERSION >= 0x0400) { shel_write(9, 0, 0x01, NULL, NULL); if (_app && prgname) menu_register(ap_id, prgname); } if (num_colors>4) Change3DType(L_MOTIF); else Change3DType(L_CUSTOM); WAppl_SetupInfo(); if (dsk) { DesktopInstalled = TRUE; WSetup_Desktop(); } InitCookies(); TInitTitle(); WInitAlert(); WInitAscii(); WindowChain->tree = desktop; if (DesktopInstalled) WDesk_Redraw(); WInitProcesses(); TShowTitle(); nkc_init(NKI_NO200HZ, VDIhandle); return TRUE; } /* * Terminate * * Frees all resources used by WinLIB. */ GLOBAL void WTerm(void) { WKillAllWindows(); free(prgnameheader); free(_MainDispatcher); free(_MainKeyDispatcher); free(WindowChain); wind_set(0, WF_NEWDESK, 0); XVDI_RestoreForGEM(); if (nkc_exit()) form_alert(1, "[3][Cannot terminate: |NKCC not de-initialized][OK]"); } /* * Terminate execution * * returns = value to be returned by WDoDial() * * Sends message to WDoDial loop to terminate. */ GLOBAL void WDie(int returns) { Life = FALSE; Return = returns; } /* * Search for window with handle 'handle' * * Returns NULL if not found, pointer to actual window otherwise */ GLOBAL WINDOW *WFindHandle(int handle) { WINDOW *ptr = WindowChain; while (ptr) if (ptr->handle == handle) return ptr; else ptr = ptr->next; return FALSE; } /* * Send a message to a window * * win = Windows to send message to * msg_buf = message buffer (same syntax as ev_mgpbuff in evnt_mesag) */ GLOBAL void WMsgWindow(WINDOW *win, int msg_buf[8]) { int dummy; int tophandle; WMoveWindow(win, -1, -1, -1, -1); switch (msg_buf[0]) { GRECT *realrect, temp, work; int pxyarray[4]; case WM_REDRAW: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } realrect = (GRECT *) (msg_buf + 4); /* nasty */ if (win->menubar) { int x, y; WUpdateWindowMenu(win, msg_buf[4], msg_buf[5], msg_buf[6], msg_buf[7]); objc_offset(win->menubar, 1, &x, &y); dummy = max(msg_buf[5], y + win->menubar[1].ob_height + 1); if (dummy > msg_buf[5]) { msg_buf[7] -= dummy - msg_buf[5]; msg_buf[5] = dummy; } } if (rc_intersect(realrect, &desk)) { WWindGet(win, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h); if (rc_intersect(realrect, &work)) if (msg_buf[7] > 0 && WCallWndDispatcher(win, msg_buf)) if (win->tree) WUpdateWindowDlg(win, msg_buf[4], msg_buf[5], msg_buf[6], msg_buf[7], 0); else { wind_update(BEG_UPDATE); graf_mouse(M_OFF, NULL); vsf_interior(VDIhandle, FIS_SOLID); vswr_mode(VDIhandle, MD_REPLACE); vsf_color(VDIhandle, 0); WWindGet(win, WF_FIRSTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h); while (temp.g_w && temp.g_h) { if (rc_intersect(&temp, realrect)) { pxyarray[0] = temp.g_x; pxyarray[1] = temp.g_y; pxyarray[2] = temp.g_x + temp.g_w - 1; pxyarray[3] = temp.g_y + temp.g_h - 1; v_bar(VDIhandle, pxyarray); } WWindGet(win, WF_NEXTXYWH, &temp.g_x, &temp.g_y, &temp.g_w, &temp.g_h); } graf_mouse(M_ON, NULL); wind_update(END_UPDATE); } } if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } msg_buf[0] = WM_PAINT; msg_buf[1] = Ap_ID; msg_buf[3] = win->handle; WMsgWindow(win, msg_buf); break; case WM_CLOSED: if (WCallWndDispatcher(win, msg_buf)) { WCruelCloseWindow(win, FALSE); WKillWindow(win); } break; case WM_KILL: WCallWndDispatcher(win, msg_buf); if (win->state & W_OPEN) /* Close window if it isn't already closed */ WCruelCloseWindow(win, FALSE); free(win->WndDispatcher); wind_delete(win->handle); /* Delete window for good */ if (win->prev) /* Remove window from chain */ win->prev->next = win->next; win->next->prev = win->prev; if (WindowChain == win) /* Make sure WindowChain doesn't point to the removed window */ WindowChain = win->next; free(win); /* And free memory */ break; case WM_ICONIFY:if (WCallWndDispatcher(win, msg_buf)) { WWindSet(win, WF_ICONIFY, msg_buf[4], msg_buf[5], msg_buf[6], msg_buf[7]); } break; case WM_UNICONIFY: if (WCallWndDispatcher(win, msg_buf)) { WWindSet(win, WF_UNICONIFY, msg_buf[4], msg_buf[5], msg_buf[6], msg_buf[7]); } break; case WM_ALLICONIFY: /* Lots of work to do here... :( */ /* But I've got the code! */ break; case WM_BOTTOMED: case WM_TOOLBAR: case WM_NEWTOP: case WM_ONTOP: case WM_CREATED:WWindGet(win, WF_TOP, &tophandle); WCallWndDispatcher(win, msg_buf); break; case WM_PAINT: WCallWndDispatcher(win, msg_buf); break; case WM_UNTOPPED: /* nasty */ case WM_HSLID: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } WCallWndDispatcher(win, msg_buf); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; case WM_ARROWED:WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } WCallWndDispatcher(win, msg_buf); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; case WM_VSLID: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } WCallWndDispatcher(win, msg_buf); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; case WM_SIZED: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } if (WCallWndDispatcher(win, msg_buf)) WMoveWindow(win, -1, -1, msg_buf[6], msg_buf[7]); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; case WM_MOVED: if (WCallWndDispatcher(win, msg_buf)) WMoveWindow(win, msg_buf[4], msg_buf[5], -1, -1); break; case WM_TOPPED: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } if (WindowChain != win && ! (win->state & W_UNUNTOPPABLE) && WindowChain->state & W_UNUNTOPPABLE) { win = WindowChain; msg_buf[3] = win->handle; } if (WCallWndDispatcher(win, msg_buf)) WTopWindow(win); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; case WM_FULLED: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } if (win->state & W_FULLERICONIFIES) WWindSet(win, WF_ICONIFY, !(win->state & W_ICONIFIED)); else { if (WCallWndDispatcher(win, msg_buf)) if (win->state & W_FULLERMINIMIZES) WWindSet(win, WF_MINIMIZE, !(win->state & W_MINIMIZED)); else { int x, y, w, h; WWindGet(win, WF_CURRXYWH, &x, &y, &w, &h); if (x == desk.g_x && y == desk.g_y && w == desk.g_w && h == desk.g_h) WWindGet(win, WF_PREVXYWH, &x, &y, &w, &h); else { x = desk.g_x; y = desk.g_y; w = desk.g_w; h = desk.g_h; } WMoveWindow(win, x, y, w, h); } if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } } break; case AP_DRAGDROP: WWindGet(win, WF_TOP, &tophandle); if (win->edobject && win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_END); win->edit_disp = FALSE; } if (WCallWndDispatcher(win, msg_buf)) WCallEtcDispatcher(msg_buf); if (win->edobject && !win->edit_disp && win->handle == tophandle && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { objc_edit(win->tree, win->edobject, 0, &win->edpos, ED_INIT); win->edit_disp = TRUE; } break; } } /* * Main loop * * This fetches messages from AES, interprets and * dispatches them to the correct windows. * * The loop exits when a WDie() call is executed * * Returns: The value specified in the WDie(value) call, or -1. * -1 means the application is to be terminated immediately, * the typical response to a AP_TERM message. */ GLOBAL int WDoDial(OBJECT *menu) { EVENT event; Life = TRUE; Return = 0; event.ev_mbclicks = 0x102; event.ev_bmask = 3; event.ev_mbstate = 0; if (menu) { event.ev_mm1flags = FALSE; event.ev_mm1x = menu->ob_x; event.ev_mm1y = menu->ob_y; event.ev_mm1width = menu->ob_width; event.ev_mm1height = menu[1].ob_height; } while (Life) { WINDOW *win; int message; event.ev_mflags = MU_MESAG | MU_BUTTON | MU_KEYBD | MU_TIMER | MU_M1; event.ev_mtlocount = (int)(0x0001L); event.ev_mthicount = (int)(0x0000L); if ((win!=NULL) && (win->timer.status)) { long tcount; tcount = win->timer.clock - (clock() * 1000 / CLK_TCK); if (tcount > 0) { event.ev_mtlocount = (int) (tcount & 0xffffL); event.ev_mthicount = (int) (tcount >> 16); } else event.ev_mtlocount = event.ev_mthicount = 0; } message = EvntMulti(&event); win = WindowChain; if (message & MU_M1) if (MenusShown) DoDeskMenu(menu); if ((message & MU_BUTTON) && ((wind_find(event.ev_mmox, event.ev_mmoy)) == DESKTOP) && (DesktopInstalled)) WDo_Desk(objc_find(desktop, 0, 10, event.ev_mmox, event.ev_mmoy), event.ev_mbreturn, TRUE); if (message & MU_MESAG) { switch (event.ev_mmgpbuf[0]) { case WM_TOPPED: if (win = WFindHandle(event.ev_mmgpbuf[3])) { if (win->state & W_BEVENT) { int dummy; long applrecord[] = { 1, 0x010000L, 0, 16, 1, 0x100001L }; GRECT rect; graf_mkstate(&event.ev_mmox, &event.ev_mmoy, &event.ev_mmobutton, &event.ev_mmokstate); if (event.ev_mmobutton & 1) { if (AES_VERSION > 0x0100) appl_tplay(applrecord, 3, 100); WMoveWindow(win, -1, -1, -1, -1); WWindGet(win, WF_WORKXYWH, &rect.g_x, &rect.g_y, &rect.g_w, &rect.g_h); if (rc_inside(event.ev_mmox, event.ev_mmoy, &rect) && ! win->tree) goto button; wind_get(win->handle, WF_WORKXYWH, &rect.g_x, &rect.g_y, &rect.g_w, &rect.g_h); if (rc_inside(event.ev_mmox, event.ev_mmoy, &rect) && ( (win->tree && (dummy = objc_find(win->tree, 0, 99, event.ev_mmox, event.ev_mmoy)) != -1 && win->tree[dummy].ob_flags & (SELECTABLE | EXIT)) || (win->menubar && objc_find(win->menubar, 2, 1, event.ev_mmox, event.ev_mmoy) != -1)) ) button: { message |= MU_BUTTON; event.ev_mbreturn = 1; } if (win->tree[dummy].ob_flags & TOUCHEXIT) { int type; graf_mkstate(&event.ev_mmox, &event.ev_mmoy, &type, &type); dummy = objc_find(win->tree, 0, 99, event.ev_mmox, event.ev_mmoy); if (dummy!=-1) { type = win->tree[dummy].ob_type >> 8; switch (type) { case FLYING: graf_mouse(FLAT_HAND, NULL); WDragBox(win->size.g_w + 1, win->size.g_h + 1, win->size.g_x, win->size.g_y, desk.g_x, desk.g_y, -1, -1, BLACK, 0, 0x0000, &win->size.g_x, &win->size.g_y, TRUE); WMoveWindow(win, win->size.g_x, win->size.g_y, -1, -1); graf_mouse(ARROW, NULL); break; case HANDSLIDE: graf_mouse(FLAT_HAND, NULL); default: { int d, button; if (win->tree[dummy].ob_flags & SELECTABLE) Objc_Change(win->tree, dummy, 0, win->tree[dummy].ob_state | SELECTED, 1); do { graf_mkstate(&d, &d, &button, &d); WCallDlgDispatcher(win, dummy); } while (button); if (win->tree[dummy].ob_flags & SELECTABLE) Objc_Change(win->tree, dummy, 0, win->tree[dummy].ob_state & ~SELECTED, 1); if (type == HANDSLIDE) graf_mouse(ARROW, NULL); } break; } } } break; } } WMsgWindow(win, event.ev_mmgpbuf); } break; case WM_CLOSED: if (win = WFindHandle(event.ev_mmgpbuf[3])) WCloseWindow(win, WC_OBJECTABLE); break; case WM_REDRAW: /* Handle window messages */ case WM_NEWTOP: case WM_ARROWED: case WM_VSLID: case WM_SIZED: case WM_FULLED: case WM_HSLID: case WM_MOVED: case WM_UNTOPPED: case WM_ONTOP: case WM_BOTTOMED: case WM_ICONIFY: case WM_UNICONIFY: case WM_ALLICONIFY: case WM_TOOLBAR: case WM_CREATED: if (win = WFindHandle(event.ev_mmgpbuf[3])) WMsgWindow(win, event.ev_mmgpbuf); break; case AP_DRAGDROP: if (win = WFindHandle(event.ev_mmgpbuf[3])) WMsgWindow(win, event.ev_mmgpbuf); else WCallEtcDispatcher(event.ev_mmgpbuf); break; case AC_OPEN: /* Program/environmental messages */ case AC_CLOSE: case SH_WDRAW: case CH_EXIT: case RESCH_COMPLETED: case AP_TERM: switch(event.ev_mmgpbuf[0]) { case AC_CLOSE: if (WCallEtcDispatcher(event.ev_mmgpbuf)) WKillAllWindows(); break; case AP_TERM: if (WCallEtcDispatcher(event.ev_mmgpbuf)) return -2; break; case SH_WDRAW: case CH_EXIT: case RESCH_COMPLETED: case AC_OPEN: WCallEtcDispatcher(event.ev_mmgpbuf); break; } break; case MN_SELECTED: /* Menu messages */ if (WCallEtcDispatcher(event.ev_mmgpbuf)) menu_tnormal(wl_menubar, event.ev_mmgpbuf[3], 1); break; } } if (message & MU_TIMER) { if (win->timer.status) { WStartTimer(win); WCallTmrDispatcher(win); } else { int mx, my, co; graf_mkstate(&mx,&my,&co,&co); co = objc_find(win->tree, 0, 99, mx, my); if (co!=-1 && (win->state & W_OPEN)) if (win->tree[co].ob_flags & EDITABLE) WGrafMouse(TEXT_CRSR); else WGrafMouse(ARROW); } } if ((message & MU_KEYBD) && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { int n_key, nxtobj, nxtchr; win = WindowChain; WMoveWindow(win, -1, -1, -1, -1); n_key = nkc_tconv((event.ev_mkreturn & 0xff) | (((long) event.ev_mkreturn & 0xff00) << 8) | ((long) event.ev_mmokstate << 24)); if ((n_key & NKF_ALT) && (n_key & NKF_CTRL)) { switch(n_key & 0xFF) { case NK_DEL: if (n_key & NKF_RSH) WCallResetDispatcher(win, 1); else WCallResetDispatcher(win, 0); goto exit_kbd; case NK_UP: case '8': if ((((n_key & 0xFF) == '8') && (n_key & NKF_NUM)) || ((n_key & 0xFF) == NK_UP)) { int m[8]; m[0] = WM_ARROWED; m[4] = ((n_key & NKF_RSH) || (n_key & NKF_LSH)) ? WA_UPPAGE : WA_UPLINE; WMsgWindow(win, m); } goto exit_kbd; case NK_DOWN: case '2': if ((((n_key & 0xFF) == '2') && (n_key & NKF_NUM)) || ((n_key & 0xFF) == NK_DOWN)) { int m[8]; m[0] = WM_ARROWED; m[4] = ((n_key & NKF_RSH) || (n_key & NKF_LSH)) ? WA_DNPAGE : WA_DNLINE; WMsgWindow(win, m); } goto exit_kbd; case '*': if ((n_key & NKF_NUM) && (win->handle!=0)) { int m[8]; m[0] = WM_FULLED; m[3] = win->handle; WMsgWindow(win, m); } goto exit_kbd; case NK_F5: Change3DType(L_MULTITOS); WRedrawAllWindows(); goto exit_kbd; case NK_F6: Change3DType(L_CUSTOM); WRedrawAllWindows(); goto exit_kbd; case NK_F7: if (num_colors>4) { Change3DType(L_MOTIF); WRedrawAllWindows(); } else WFormCustAlert(3, " Motif look ", "Sorry, the Motif 3D style look", "is only available in a color", "mode with more than 4 colors.", "Please change mode or resolut-", "ions to see the mode.", " ", "Okay", " "); goto exit_kbd; case NK_F8: Change3DType(L_GENEVA); WRedrawAllWindows(); goto exit_kbd; case NK_F9: Change3DType(L_WINLIB); WRedrawAllWindows(); goto exit_kbd; case NK_F10: Change3DType(L_STANDARD); WRedrawAllWindows(); goto exit_kbd; case ' ': WRedrawAllWindows(); goto exit_kbd; case NK_ESC: WCloseWindow(win, WC_OBJECTABLE); goto exit_kbd; case NK_TAB: WTopWindow(NULL); goto exit_kbd; case NK_BS: WKillAllWindows(); goto exit_kbd; /* case NK_HELP: CallInternalHelp(); goto exit_kbd; */ case NK_ENTER: { int x, y, w, h; WWindGet(win, WF_WORKXYWH, &x, &y, &w, &h); WRedrawWindow(win, x, y, w, h); } goto exit_kbd; } } if (win->state & W_OPEN) { if (WCallWKeyDispatcher(win, n_key)) if (WCallKeyDispatcher(n_key)) if (win->tree) if (WForm_keybd(win, event.ev_mkreturn, event.ev_mmokstate, &nxtobj, &nxtchr)) { if (nxtchr) objc_edit(win->tree, win->edobject, nxtchr, &win->edpos, ED_CHAR); if (nxtobj != win->edobject) { edit_off(win); win->edobject = nxtobj; edit_on(win); } } else { if (!(win->tree[nxtobj].ob_flags & RBUTTON)) Objc_Change(win->tree, nxtobj, 0, win->tree[nxtobj].ob_state ^ SELECTED, 1); else { int act = nxtobj, lst, new; OBJECT *obptr = win->tree + nxtobj; if (!(win->tree[nxtobj].ob_state & SELECTED)) Objc_Change(win->tree, nxtobj, 0, win->tree[nxtobj].ob_state | SELECTED, 1); for(;;) { lst = act; new = obptr->ob_next; for(;;) { act = new; obptr = win->tree + act; if (obptr->ob_tail == lst) { new = obptr->ob_head; lst = act; } else { if (act == nxtobj) goto rb_exit; if ((obptr->ob_state & SELECTED) && (obptr->ob_flags & RBUTTON)) { Objc_Change(win->tree, act, 0, obptr->ob_state ^ SELECTED, 1); goto rb_exit; } else break; } } } } if (!(win->tree[nxtobj].ob_flags & RBUTTON || win->tree[nxtobj].ob_type & 0x8000)) Objc_Change(win->tree, nxtobj, 0, NORMAL, 1); rb_exit: WCallDlgDispatcher(win, nxtobj); } } else WCallKeyDispatcher(n_key); } exit_kbd: if ((message & MU_BUTTON) && !(win->state & W_MINIMIZED) && !(win->state & W_ICONIFIED)) { int nxtobj, tophandle; if (win = WFindHandle(wind_find(event.ev_mmox, event.ev_mmoy))) { if (WindowChain->state & W_MODAL) win = WindowChain; WMoveWindow(win, -1, -1, -1, -1); WWindGet(win, WF_TOP, &tophandle); if (win->menubar && objc_find(win->menubar, 1, 1, event.ev_mmox, event.ev_mmoy) != -1) domenu(win); else if (win->tree && (nxtobj = objc_find(win->tree, 0, 99, event.ev_mmox, event.ev_mmoy)) != -1 && event.ev_mbreturn==1) if (win->tree[nxtobj].ob_flags & (SELECTABLE | EDITABLE)) { WForm_button(win, nxtobj, event.ev_mbreturn, &nxtobj); if (win->tree[nxtobj].ob_flags & EDITABLE && nxtobj != win->edobject) if (win->handle == tophandle) { int pos = win->edpos; edit_off(win); win->edobject = nxtobj; win->edpos = pos; edit_on(win); } else win->edobject = nxtobj; if (win->tree[nxtobj].ob_flags & EDITABLE) if (win->handle == tophandle) { register char *t = win->tree[win->edobject].ob_spec.tedinfo->te_ptext; register int pos; t += pos = find_position(win->tree, win->edobject, event.ev_mmox); edit_pos(win, pos); win->edobject = nxtobj; } else win->edobject = nxtobj; if (win->tree[nxtobj].ob_flags & SELECTABLE && !(win->tree[nxtobj].ob_flags & RBUTTON || win->tree[nxtobj].ob_type & 0x8000)) Objc_Change(win->tree, nxtobj, 0, NORMAL, 1); if (win->tree[nxtobj].ob_flags & (EXIT | TOUCHEXIT)) WCallDlgDispatcher(win, nxtobj); } else if (win->tree[nxtobj].ob_flags & TOUCHEXIT) { int type = win->tree[nxtobj].ob_type >> 8; int flag = win->tree[nxtobj].ob_flags; int dummy, button; if (type == FLYING) { int m[8]; graf_mouse(FLAT_HAND, NULL); WDragBox(win->size.g_w + 1, win->size.g_h + 1, win->size.g_x, win->size.g_y, desk.g_x, desk.g_y, -1, -1, BLACK, 0, 0x0000, &win->size.g_x, &win->size.g_y, TRUE); m[0] = WM_MOVED; m[3] = win->handle; m[4] = win->size.g_x; m[5] = win->size.g_y; m[6] = win->size.g_w; m[7] = win->size.g_h; WMsgWindow(win, m); graf_mouse(ARROW, NULL); } if (flag & HANDSLIDE) graf_mouse(FLAT_HAND, NULL); if (type!=FLYING) Objc_Change(win->tree, nxtobj, 0, win->tree[nxtobj].ob_state | SELECTED, 1); do { graf_mkstate(&dummy, &dummy, &button, &dummy); WCallDlgDispatcher(win, nxtobj); } while (button == 1); if (type!=FLYING) Objc_Change(win->tree, nxtobj, 0, win->tree[nxtobj].ob_state & ~SELECTED, 1); if (flag & HANDSLIDE) graf_mouse(ARROW, NULL); } else WCallBtnDispatcher(win, event.ev_mmox, event.ev_mmoy, event.ev_mmobutton, event.ev_mmokstate, event.ev_mbreturn); } } } return Return; }